/**
 * Copyright  2025, Hai Yue Xing He  ZHAO LIMIN
 * 
 * @author        ZHAO LIMIN
 * @version       1.0.1
 * @since         2025-04
 * 抛物线轨迹工具类 增强版抛物线轨迹工具类（包含坐标转换功能）
 */
import {HYXH_GRAVITY, HYXH_RESOLUTION_RATIO} from "../HYXHCommon";      //常量地球重力及分辨率  
import {Vec2 } from "cc";                                               //坐标
import {HYXHCoordTools} from "../coord/HYXHCoordTools";                 //坐标转换工具类

class HYXHEnhancedParabolaUtils {
    /**
     * 世界坐标转屏幕坐标
     * @param worldPos 世界坐标系中的位置
     * @param viewport 视口设置
     * @returns 屏幕坐标
     */
    static worldToScreen(
        worldPos: { x: number; y: number },
        viewport: {
            center: { x: number; y: number };
            zoom: number;
            screenSize: { width: number; height: number };
            yFlip?: boolean; // 是否翻转Y轴（屏幕坐标系通常Y轴向下）
        }
    ): { x: number; y: number } {
        const screenX = (worldPos.x - viewport.center.x) * viewport.zoom + viewport.screenSize.width / 2;
        let screenY = (worldPos.y - viewport.center.y) * viewport.zoom + viewport.screenSize.height / 2;
        
        if (viewport.yFlip) {
            screenY = viewport.screenSize.height - screenY;
        }
        
        return { x: screenX, y: screenY };
    }

    /**
     * 屏幕坐标转世界坐标
     * @param screenPos 屏幕坐标
     * @param viewport 视口设置
     * @returns 世界坐标
     */
    static screenToWorld(
        screenPos: { x: number; y: number },
        viewport: {
            center: { x: number; y: number };
            zoom: number;
            screenSize: { width: number; height: number };
            yFlip?: boolean;
        }
    ): { x: number; y: number } {
        let worldY = (screenPos.y - viewport.screenSize.height / 2) / viewport.zoom + viewport.center.y;
        
        if (viewport.yFlip) {
            worldY = ((viewport.screenSize.height - screenPos.y) - viewport.screenSize.height / 2) / viewport.zoom + viewport.center.y;
        }
        
        return {
            x: (screenPos.x - viewport.screenSize.width / 2) / viewport.zoom + viewport.center.x,
            y: worldY
        };
    }

    /**
     * 计算抛物线轨迹（世界坐标系）
     * @param initialPos 初始位置（世界坐标）
     * @param velocity 初始速度（世界坐标）
     * @param gravity 重力（世界坐标，默认9.8）
     * @param time 时间
     * @returns 世界坐标位置
     */
    static calculateWorldPosition(
        initialPos: { x: number; y: number },
        velocity: { x: number; y: number },
        gravity: number = 9.8,
        time: number
    ): { x: number; y: number } {
        return {
            x: initialPos.x + velocity.x * time,
            y: initialPos.y + velocity.y * time + 0.5 * gravity * time * time
        };
    }

    /**
     * 生成轨迹并转换为屏幕坐标
     * @param initialPos 初始世界坐标
     * @param velocity 初始速度
     * @param gravity 重力
     * @param duration 持续时间
     * @param viewport 视口设置
     * @param pointCount 轨迹点数
     * @returns 屏幕坐标轨迹
     */
    static generateScreenTrajectory(
        initialPos: { x: number; y: number },
        velocity: { x: number; y: number },
        gravity: number,
        duration: number,
        viewport: {
            center: { x: number; y: number };
            zoom: number;
            screenSize: { width: number; height: number };
            yFlip?: boolean;
        },
        pointCount: number = 30
    ): Array<{ x: number; y: number }> {
        const worldTrajectory = this.generateWorldTrajectory(
            initialPos,
            velocity,
            gravity,
            duration,
            pointCount
        );
        
        return worldTrajectory.map(pos => this.worldToScreen(pos, viewport));
    }

    /**
     * 生成世界坐标系轨迹
     * @param initialPos 初始位置
     * @param velocity 初始速度
     * @param gravity 重力
     * @param duration 持续时间
     * @param pointCount 轨迹点数
     * @returns 世界坐标轨迹
     */
    private static generateWorldTrajectory(
        initialPos: { x: number; y: number },
        velocity: { x: number; y: number },
        gravity: number,
        duration: number,
        pointCount: number
    ): Array<{ x: number; y: number }> {
        const landingTime = this.calculateLandingTime(initialPos, velocity, gravity);
        const endTime = landingTime !== null ? Math.min(duration, landingTime) : duration;
        
        const trajectory: Array<{ x: number; y: number }> = [];
        for (let i = 0; i <= pointCount; i++) {
            const time = (i / pointCount) * endTime;
            trajectory.push(this.calculateWorldPosition(initialPos, velocity, gravity, time));
        }
        return trajectory;
    }

    /**
     * 计算落地时间（世界坐标）
     */
    private static calculateLandingTime(
        initialPos: { x: number; y: number },
        velocity: { x: number; y: number },
        gravity: number
    ): number | null {
        const landingTime = -2 * velocity.y / gravity;
        return landingTime > 0 ? landingTime : null;
    }

    /**
     * 坐标旋转（可用于倾斜抛物线）
     * @param point 原始坐标
     * @param angle 旋转角度（弧度）
     * @param origin 旋转中心点
     * @returns 旋转后的坐标
     */
    static rotatePoint(
        point: { x: number; y: number },
        angle: number,
        origin: { x: number; y: number } = { x: 0, y: 0 }
    ): { x: number; y: number } {
        const cos = Math.cos(angle);
        const sin = Math.sin(angle);
        const x = point.x - origin.x;
        const y = point.y - origin.y;
        
        return {
            x: x * cos - y * sin + origin.x,
            y: x * sin + y * cos + origin.y
        };
    }

    /**
     * 坐标缩放
     * @param point 原始坐标
     * @param scale 缩放比例 {x, y}
     * @param origin 缩放中心点
     * @returns 缩放后的坐标
     */
    static scalePoint(
        point: { x: number; y: number },
        scale: { x: number; y: number },
        origin: { x: number; y: number } = { x: 0, y: 0 }
    ): { x: number; y: number } {
        return {
            x: (point.x - origin.x) * scale.x + origin.x,
            y: (point.y - origin.y) * scale.y + origin.y
        };
    }
}

// 使用示例
const viewport = {
    center: { x: 0, y: 0 },   // 世界坐标系中心
    zoom: 100,                // 100像素/单位
    screenSize: { width: 800, height: 600 },
    yFlip: true               // 屏幕Y轴向下
};

// 世界坐标系中的抛物线参数
const worldStart = { x: -2, y: 1 };
const velocity = { x: 1, y: 2 };
const gravity = 9.8;

// 生成屏幕坐标轨迹
const screenTrajectory = HYXHEnhancedParabolaUtils.generateScreenTrajectory(
    worldStart,
    velocity,
    gravity,
    1.5, // 持续时间1.5秒
    viewport
);

console.log('屏幕坐标轨迹:', screenTrajectory);

// 坐标旋转示例
const point = { x: 1, y: 0 };
const rotated = HYXHEnhancedParabolaUtils.rotatePoint(point, Math.PI / 4); // 旋转45度
console.log('旋转后的坐标:', rotated);

// 坐标缩放示例
const scaled = HYXHEnhancedParabolaUtils.scalePoint(point, { x: 2, y: 0.5 });
console.log('缩放后的坐标:', scaled);